home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1998-10-30 | 48.2 KB | 1,468 lines
FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) NNNNAAAAMMMMEEEE handle_sigfpes - floating-point exception handler package SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS ####iiiinnnncccclllluuuuddddeeee <<<<ffffssssiiiiggggffffppppeeee....hhhh>>>> ssssuuuubbbbrrrroooouuuuttttiiiinnnneeee hhhhaaaannnnddddlllleeee____ssssiiiiggggffffppppeeeessss((((oooonnnnooooffffffff,,,,eeeennnn____mmmmaaaasssskkkk,,,,uuuusssseeeerrrr____rrrroooouuuuttttiiiinnnneeee,,,,aaaabbbboooorrrrtttt____aaaaccccttttiiiioooonnnn,,,,aaaabbbboooorrrrtttt____rrrroooouuuuttttiiiinnnneeee)))) iiiinnnntttteeeeggggeeeerrrr ****4444 oooonnnnooooffffffff,,,, eeeennnn____mmmmaaaasssskkkk,,,, aaaabbbboooorrrrtttt____aaaaccccttttiiiioooonnnn iiiinnnntttteeeeggggeeeerrrr ****4444 aaaabbbboooorrrrtttt____rrrroooouuuuttttiiiinnnneeee,,,, uuuusssseeeerrrr____rrrroooouuuuttttiiiinnnneeee eeeexxxxtttteeeerrrrnnnnaaaallll aaaabbbboooorrrrtttt____rrrroooouuuuttttiiiinnnneeee,,,, uuuusssseeeerrrr____rrrroooouuuuttttiiiinnnneeee ssssttttrrrruuuuccccttttuuuurrrreeee ////ssssiiiiggggffffppppeeee____tttteeeemmmmppppllllaaaatttteeee//// iiiinnnntttteeeeggggeeeerrrr **** 4444 rrrreeeeppppllllssss iiiinnnntttteeeeggggeeeerrrr **** 4444 ccccoooouuuunnnntttt iiiinnnntttteeeeggggeeeerrrr **** 4444 ttttrrrraaaacccceeee iiiinnnntttteeeeggggeeeerrrr **** 4444 aaaabbbboooorrrrtttt iiiinnnntttteeeeggggeeeerrrr **** 4444 eeeexxxxiiiitttt eeeennnndddd ssssttttrrrruuuuccccttttuuuurrrreeee rrrreeeeccccoooorrrrdddd ////ssssiiiiggggffffppppeeee____tttteeeemmmmppppllllaaaatttteeee//// ffffssssiiiiggggffffppppeeee ((((0000::::FFFFPPPPEEEE____NNNN____EEEEXXXXCCCCEEEEPPPPTTTTIIIIOOOONNNN____TTTTYYYYPPPPEEEESSSS)))) ccccoooommmmmmmmoooonnnn //// ssssiiiiggggffffppppeeee //// ffffssssiiiiggggffffppppeeee ((((0000::::FFFFPPPPEEEE____NNNN____EEEEXXXXCCCCEEEEPPPPTTTTIIIIOOOONNNN____TTTTYYYYPPPPEEEESSSS)))) iiiinnnntttteeeeggggeeeerrrr **** 4444 rrrreeeessssuuuullllttttssss((((0000::::FFFFPPPPEEEE____NNNN____IIIINNNNVVVVAAAALLLLIIIIDDDDOOOOPPPP____RRRREEEESSSSUUUULLLLTTTTSSSS)))) ccccoooommmmmmmmoooonnnn //// iiiinnnnvvvvaaaalllliiiiddddoooopppp____rrrreeeessssuuuullllttttssss //// rrrreeeessssuuuullllttttssss iiiinnnntttteeeeggggeeeerrrr **** 4444 iiiinnnnvvvvoooopppp((((0000::::FFFFPPPPEEEE____NNNN____IIIINNNNVVVVAAAALLLLIIIIDDDDOOOOPPPP____OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS)))) ccccoooommmmmmmmoooonnnn //// iiiinnnnvvvvaaaalllliiiiddddoooopppp____ooooppppeeeerrrraaaannnnddddssss //// iiiinnnnvvvvoooopppp ssssuuuubbbbrrrroooouuuuttttiiiinnnneeee uuuusssseeeerrrr____rrrroooouuuuttttiiiinnnneeee ((((ccccoooonnnntttteeeexxxxtttt,,,, rrrreeeessssuuuulllltttt)))) iiiinnnntttteeeeggggeeeerrrr **** 4444 ccccoooonnnntttteeeexxxxtttt ((((5555)))) iiiinnnntttteeeeggggeeeerrrr **** 4444 rrrreeeessssuuuulllltttt ((((2222)))) ssssuuuubbbbrrrroooouuuuttttiiiinnnneeee aaaabbbboooorrrrtttt____rrrroooouuuuttttiiiinnnneeee ((((ppppcccc)))) iiiinnnntttteeeeggggeeeerrrr **** 4444 ppppcccc For 64 bit programs, use the following prototype for abort_routine: ssssuuuubbbbrrrroooouuuuttttiiiinnnneeee aaaabbbboooorrrrtttt____rrrroooouuuuttttiiiinnnneeee ((((ppppcccc)))) iiiinnnntttteeeeggggeeeerrrr **** 8888 ppppcccc DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN The MIPS floating-point accelerator may raise floating-point exceptions, signal SIGFPE, due to five conditions: FFFFPPPPEEEE____OOOOVVVVEEEERRRRFFFFLLLL(_o_v_e_r_f_l_o_w), FFFFPPPPEEEE____UUUUNNNNDDDDEEEERRRRFFFFLLLL(_u_n_d_e_r_f_l_o_w), FFFFPPPPEEEE____DDDDIIIIVVVVZZZZEEEERRRROOOO(_d_i_v_i_d_e-_b_y-_z_e_r_o), FFFFPPPPEEEE____IIIINNNNEEEEXXXXAAAACCCCTTTT(_i_n_e_x_a_c_t _r_e_s_u_l_t), or FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD(_i_n_v_a_l_i_d _o_p_e_r_a_n_d, e.g., infinity). Usually these conditions are masked, and do not cause a floating-point exception. Instead, a default value is substituted for the result of the operation, and the program continues silently. This event may be intercepted by PPPPaaaaggggeeee 1111 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) causing an exception to be raised. When this occurs, the operating system generates a SIGFPE signal. The integer arithmetic instructions add, addi, dadd, daddi, sub, and dsub also generate a SIGFPE signal when the result of the operation overflows (condition FFFFPPPPEEEE____IIIINNNNTTTT____OOOOVVVVEEEERRRRFFFFLLLL(_i_n_t_e_g_e_r _o_v_e_r_f_l_o_w)). (At the moment, SGI compilers generate only unsigned versions of these instructions, which do not generate a signal on overflow. However it is still possible to generate these instructions via assembly language). Once an exception is raised, the specific conditions which caused the exception may be determined, and more appropriate action taken. The library lllliiiibbbbffffppppeeee....ssssoooo provides two methods to unmask and handle these conditions: the subroutine hhhhaaaannnnddddlllleeee____ssssiiiiggggffffppppeeeessss, and the environment variable TTTTRRRRAAAAPPPP____FFFFPPPPEEEE. Both methods provide a mechanism for unmasking each condition except FFFFPPPPEEEE____IIIINNNNEEEEXXXXAAAACCCCTTTT, for _h_a_n_d_l_i_n_g and classifying exceptions arising from them, and for substituting either a default value or a chosen one. They also provide mechanisms to count, trace, exit or abort on enabled exceptions. If the user supplies his own call to hhhhaaaannnnddddlllleeee____ssssiiiiggggffffppppeeeessss he should leave environment variable TTTTRRRRAAAAPPPP____FFFFPPPPEEEE undefined or set to OFF. TTTTRRRRAAAAPPPP____FFFFPPPPEEEE is supported for Fortran, C and Pascal. HHHHaaaannnnddddlllleeee____ssssiiiiggggffffppppeeeessss is supported for C and Fortran. Calling the subroutine is the preferred method when preparing software for others to use, since it relieves the user of any need to know about the TTTTRRRRAAAAPPPP____FFFFPPPPEEEE environment variable. The environment variable is preferable if one wants to experiment or allow any user to experiment with with different trap behaviors with minimum effort. Libfpe uses System V signal handling and will not work with programs which use Berkeley signal handling. Note that the preferred method for flushing denormals to zero is to set the FS bit to 1 in the floating point control status register. The following routine (written in c) can be used to set/clear the FS bit. PPPPaaaaggggeeee 2222 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) #include <sys/fpu.h> void flush_to_zero_(int *on_off) { union fpc_csr n; n.fc_word = get_fpc_csr(); if ( (*on_off) == 0 ) { n.fc_struct.flush = 0; } else { n.fc_struct.flush = 1; } set_fpc_csr(n.fc_word); } Example: integer flag c enable flush to zero flag = 1 call flush_to_zero( flag ) Note that if the FS bit in the floating point control status register is set, it remains set after calling handle_sigfpes(FPE_OFF, ... Be sure to read the section NOTES FOR R8000, below, which describes the behavior of libfpe.so on the R8000 processor. HHHHAAAANNNNDDDDLLLLEEEE____SSSSIIIIGGGGFFFFPPPPEEEESSSS SSSSUUUUBBBBRRRROOOOUUUUTTTTIIIINNNNEEEE The values in the global arrays are described in the section WWWWHHHHEEEENNNN AAAANNNN EEEEXXXXCCCCEEEEPPPPTTTTIIIIOOOONNNN IIIISSSS EEEENNNNCCCCOOOOUUUUNNNNTTTTEEEERRRREEEEDDDD later in this man page. The arguments to _h_a_n_d_l_e__s_i_g_f_p_e_s are as follows: _o_n_o_f_f is a flag indicating whether handling is being turned on (_o_n_o_f_f == _F_P_E__O_N) or off (_o_n_o_f_f == _F_P_E__O_F_F). (_o_n_o_f_f == _F_P_E__D_E_B_U_G) is another way to turn on handling. Information from the fsigfpe structure will be printed if (_o_n_o_f_f == _F_P_E__D_E_B_U_G). (all the names used in this document are defined in _f_s_i_g_f_p_e._h). PPPPaaaaggggeeee 3333 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) _e_n__m_a_s_k indicates which of the five conditions should be unmasked, enabling them to raise floating-point exceptions. _e_n__m_a_s_k is only valid if onoff == FPE_ON or onoff == FPE_DEBUG, and is the bitwise or of one or more of the constants FPE_EN_UNDERFL, FPE_EN_OVERFL, FPE_EN_DIVZERO, FPE_EN_INVALID, and FPE_EN_INT_OVERFL (defined in _f_s_i_g_f_p_e._h). _u_s_e_r__r_o_u_t_i_n_e: hhhhaaaannnnddddlllleeee____ssssiiiiggggffffppppeeeessss provides a mechanism for setting the result of the operation to any one of a set of well-known values. If full control over the value of selected operations is desired for one or more exception conditions, a subroutine _u_s_e_r__r_o_u_t_i_n_e must be provided. For these selected exception conditions, _u_s_e_r__r_o_u_t_i_n_e will be called to set the value resulting from the operation. Pass a 0 (plain 0 is adequate) if you do not wish to provide a _u_s_e_r__r_o_u_t_i_n_e . _a_b_o_r_t__a_c_t_i_o_n: If the handler encounters an unexpected condition, an inconsistency, or begins looping, the flag _a_b_o_r_t__a_c_t_i_o_n indicates what action should be taken. Another option is for the user to specify that he is supplying his own floating point exception handler as the default handler. Legal values are: ____________________________________________________________ instruct the floating- point-accelerator to cease causing exceptions and continue. (i.e., disable handling) FPE_TURN_OFF_HANDLER_ON_ERROR ____________________________________________________________ kill the process after giving an error message and calling a user- supplied cleanup routine if one is provided via the abort_routine parameter. FPE_ABORT_ON_ERROR ____________________________________________________________ install the indicated user routine as the handler when such an error is encountered. Future floating-point exceptions will branch to the user- routine. (see signal(2)) FPE_REPLACE_HANDLER_ON_ERROR ____________________________________________________________ install the indicated user routine as the handler immediately. Future floating-point exceptions will branch to the user- routine. (see signal(2)) ||||||||||||||||||||||||||| ||||||||||||||||||||||||||| PPPPaaaaggggeeee 4444 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FPE_USER_HANDLER |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||||||||||||||||||||||||| PPPPaaaaggggeeee 5555 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) _____________________________________________________________ | | _a_b_o_r_t__r_o_u_t_i_n_e: When a fatal error (i.e., one described under _a_b_o_r_t__a_c_t_i_o_n above) is encountered, _a_b_o_r_t__r_o_u_t_i_n_e is used as the address of a user subroutine. If abort_action is FPE_ABORT_ON_ERROR, and _a_b_o_r_t__r_o_u_t_i_n_e is valid, it is called before aborting, and passed a pointer to the instruction causing the exception as its single argument. In this case, the user's abort_routine should be defined as subroutine abort_routine(pc) integer *4 pc for 32 bit programs. (Use integer *8 for 64 bit programs.) If _a_b_o_r_t__a_c_t_i_o_n is FPE_REPLACE_HANDLER_ON_ERROR, and _a_b_o_r_t__r_o_u_t_i_n_e is valid, it will be installed as the new handler. In this case, the instruction which caused the unexpected exception will be re-executed, causing a new exception, and _a_b_o_r_t__r_o_u_t_i_n_e entered. Pass a %val(0) if you do not wish to provide an _a_b_o_r_t__a_c_t_i_o_n routine. If _a_b_o_r_t__a_c_t_i_o_n is FPE_USER_HANDLER, and _a_b_o_r_t__r_o_u_t_i_n_e is valid, it will be installed immediately as the default floating point exception handler. If the user routine is to be invoked as a floating point exception handler, the following prototype (written in c) should be used (see <sigfpe.h> and signal(5)): int user_handler( sig, code, sc ) int sig, code; struct sigcontext *sc; Routine user_handler should return 0 to continue processing of the user's code and a non-zero value to disconnect user_handler as the floating point exception handler. User_handler should not issue a call to signal(), nor should it update the program counter in the sigcontext area, because these actions are done in the routine which calls it. A user handler can determine which type of exception has occurred by calling routine __fpe_trap_type(). This routine returns one of FPE_UNDERFL, FPE_OVERFL, etc. as appropriate. Users can supply separate handlers for each exception type by making multiple calls to handle_sigfpes. See the third example below. Similarly, trap handling for one or more exception types can be turned off by or-ing the appropriate combination of masks in the second parameter to handle_sigfpes. call handle_sigfpes(FPE_OFF, 0, ... disables handling of all SIGFPE signals. PPPPaaaaggggeeee 6666 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) EEEEXXXXAAAAMMMMPPPPLLLLEEEE OOOOFFFF HHHHAAAANNNNDDDDLLLLEEEE____SSSSIIIIGGGGFFFFPPPPEEEESSSS #include <fsigfpe.h> C call this during program startup C to set underflowing values to zero C C underflow to zero fsigfpe(FPE_UNDERFL).repls = FPE_ZERO C C only trap on underflow handle_sigfpes(_ON, FPE_EN_UNDERFL , %val(0), FPE_ABORT_ON_ERROR, %val(0)); The above example does one thing only: it sets up traps of underflow which change the resulting value to zero. The following is a more complicated example. #include <fsigfpe.h> C underflow to zero fsigfpe(FPE_UNDERFL).repls = FPE_ZERO C substitute max real/double precision value on overflow fsigfpe(FPE_OVERFL).repls=FPE_MAX C trace after 5 fsigfpe(FPE_UNDERFL).trace=5 fsigfpe(FPE_OVERFL).trace =5 fsigfpe(FPE_DIVZERO).trace=5 fsigfpe(FPE_INVALID).trace=5 fsigfpe(FPE_INT_OVERFL).trace=5 C counts at end fsigfpe(FPE_UNDERFL).count=2147483647 fsigfpe(FPE_OVERFL).count =2147483647 fsigfpe(FPE_DIVZERO).count=2147483647 fsigfpe(FPE_INVALID).count=2147483647 fsigfpe(FPE_INT_OVERFL).count=2147483647 C abort after 100 underflows or 100 overflows fsigfpe(FPE_UNDERFL).abort=100 fsigfpe(FPE_OVERFL).abort =100 C abort on first divide by zero or hundredth invalid fsigfpe(FPE_DIVZERO).abort=1 fsigfpe(FPE_INVALID).abort=100 PPPPaaaaggggeeee 7777 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) call handle_sigfpes(FPE_ON, x FPE_EN_UNDERFL + FPE_EN_OVERFL + x FPE_EN_DIVZERO + FPE_EN_INVALID, x %val(0), x FPE_ABORT_ON_ERROR, x %val(0)) C do the real application work here The example counts all traps, traces the first five exceptions of each kind, aborts on the first divide by zero, or the 100th overflow. It replaces zero for underflows, max float/double for overflows, max integer for integer overflows, and the default values for divide by zero, invalid operands, and integer overflows. The environment variable example below does the same thing. The last example shows how to enable different handlers for various exception types. #include <fsigfpe.h> external my_invalid_handler c counts at end fsigfpe(FPE_UNDERFL).count=2147483647 fsigfpe(FPE_OVERFL).count =2147483647 fsigfpe(FPE_DIVZERO).count=2147483647 fsigfpe(FPE_INVALID).count=2147483647 fsigfpe(FPE_INT_OVERFL).count=2147483647 c enable trapping on overflow, using libfpe's trap handler call handle_sigfpes(FPE_ON, FPE_EN_OVERFL, 0, 0, 0) c enable trapping on invalid, using user's own trap handler call handle_sigfpes(FPE_ON, FPE_EN_INVALID, my_invalid_handler, 0, 0) c do the real application work here ... c turn off trapping of overflows call handle_sigfpes(FPE_OFF, FPE_EN_OVERFL, 0, 0, 0) ... c turn off all handling of SIGFPE signals PPPPaaaaggggeeee 8888 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) call handle_sigfpes(FPE_OFF, 0, 0, 0, 0) TTTTHHHHEEEE EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT VVVVAAAARRRRIIIIAAAABBBBLLLLEEEE TTTTRRRRAAAAPPPP____FFFFPPPPEEEE If the code has been linked with lllliiiibbbbffffppppeeee....ssssoooo the runtime startup routine will check for the environment variable "TTTTRRRRAAAAPPPP____FFFFPPPPEEEE". The string read as the value of TTTTRRRRAAAAPPPP____FFFFPPPPEEEE will be interpreted and hhhhaaaannnnddddlllleeee____ssssiiiiggggffffppppeeeessss will be called with the resulting values. TTTTRRRRAAAAPPPP____FFFFPPPPEEEE is read in upper case letters only. The string assigned to TTTTRRRRAAAAPPPP____FFFFPPPPEEEE may be in upper case or lower case. TTTTRRRRAAAAPPPP____FFFFPPPPEEEE can take one of two forms: either a global value, or a list of individual items. global values: Execute the program with no trap handling enabled. Same as TTTTRRRRAAAAPPPP____FFFFPPPPEEEE undefined. Same as linking without libfpe.so "" or OFF ON Same as TTTTRRRRAAAAPPPP____FFFFPPPPEEEE====""""AAAALLLLLLLL====DDDDEEEEFFFFAAAAUUUULLLLTTTT"""". Alternately, replacement values and actions may be specified for each of the possible trap types individually. This is accomplished by setting the environment variable as follows: setenv TTTTRRRRAAAAPPPP____FFFFPPPPEEEE "item;item;item...." an item can be one of the following: Where traptype defines the specific floating point exception to enable, and statuslist defines the list of actions upon encountering the trap. traptype=statuslist Confirm the parsing of the environment variable, and the trap actions. DEBUG Traptype can be one of the following literal strings: PPPPaaaaggggeeee 9999 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) UNDERFL underflow OVERFL overflow DIVZERO divide by zero INVALID invalid operand INT_OVERFL integer overflow ALL all of the above Statuslist is a list separated by commas. It contains an optional symbolic replacement value, and an optional list of actions. symbolic replacement values: DEFAULT Do not override the predefined default values. IEEE Maps to integer code FPE_APPROPRIATE. APPROPRIATE Maps to integer code FPE_APPROPRIATE. ZERO Maps to integer code FPE_ZERO. FLUSH_ZERO Maps to integer code FPE_FLUSH_ZERO (R4000 and later processors). FLUSH_ZERO Maps to integer code FPE_ZERO (other processors). MIN Maps to integer code FPE_MIN. MAX Maps to integer code FPE_MAX. INF Maps to integer code FPE_INF. NAN Maps to integer code FPE_NAN. All actions take an optional integer in parentheses: Note: for any traps that have an action and no specified replacement value, the DEFAULT replacement value will be used. A count of the trap type will be printed to stderr every nth trap, and at the end of the program. Default is INT_MAX. COUNT(n) Core dump and abort the program upon encountering the nth trap. Default is 1. ABORT(n) Exit program upon encountering the nth trap. Default is 1. EXIT(n) If a trap is encountered, Print a stack trace to stderr up to n times. Default is 10. TRACE(n) PPPPaaaaggggeeee 11110000 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) EEEEXXXXAAAAMMMMPPPPLLLLEEEE OOOOFFFF TTTTRRRRAAAAPPPP____FFFFPPPPEEEE setenv TTTTRRRRAAAAPPPP____FFFFPPPPEEEE "ALL=COUNT; UNDERFL=ZERO; OVERFL=TRACE(5), ABORT(100); DIVZERO=ABORT" The example counts all traps, trace the first five overflows, abort on the first divide by zero, or the 100th overflow. It Replaces zero for underflows, the "appropriate" value for overflows, divide by zero, and invalid operands. WWWWHHHHEEEENNNN AAAANNNN EEEEXXXXCCCCEEEEPPPPTTTTIIIIOOOONNNN IIIISSSS EEEENNNNCCCCOOOOUUUUNNNNTTTTEEEERRRREEEEDDDD When an exception is encountered, the handler examines the instruction causing the exception, the state of the floating-point accelerator and the sigfpe structure to determine the correct action to take, and the program is continued. In the cases of FFFFPPPPEEEE____UUUUNNNNDDDDEEEERRRRFFFFLLLL,,,, FFFFPPPPEEEE____OOOOVVVVEEEERRRRFFFFLLLL,,,, FFFFPPPPEEEE____DDDDIIIIVVVVZZZZEEEERRRROOOO,,,, and some instances of FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD,,,, an appropriate value is substituted for the result of the operation, and the instruction which caused the exception is skipped. For most exceptions arising due to an invalid operand (FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD exceptions), more meaningful behavior may be obtained by replacing an erroneous operand. For these conditions, the operand is replaced, and the instruction re-issued. _s_i_g_f_p_e: For each enabled exception, the sigfpe structure contains the fields: repls, count, trace, exit and abort. For each enabled exception <p>, and each non-zero entry <n> in the sigfpe structure, the trap handler will take the following actions: ccccoooouuuunnnntttt:::: A count of all enabled traps will be printed to stderr at the end of execution of the program , and every at <n>th exception <p>. ttttrrrraaaacccceeee:::: A dbx stack trace will be printed to stderr every exception <p>, up to <n> times. You must have dbx installed on your system to use this option. aaaabbbboooorrrrtttt:::: Core dump and abort program upon encountering the <n>th exception <p>. The abort option takes precedence over the exit option. eeeexxxxiiiitttt:::: Exit program upon encountering the <n>th exception <p>. rrrreeeeppppllllssss:::: Each of the exceptions FFFFPPPPEEEE____UUUUNNNNDDDDEEEERRRRFFFFLLLL, FFFFPPPPEEEE____OOOOVVVVEEEERRRRFFFFLLLL, FFFFPPPPEEEE____DDDDIIIIVVVVZZZZEEEERRRROOOO and FFFFPPPPEEEE____IIIINNNNTTTT____OOOOVVVVEEEERRRRFFFFLLLL has an associated default value which is used as the result of the operation causing the exception. These default values may be overridden by initializing this integer value. This value is interpreted as an integer code used to select one of a set of replacement values, or to indicate that the routine _u_s_e_r__r_o_u_t_i_n_e is responsible for setting the value. PPPPaaaaggggeeee 11111111 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) These integer codes are listed below: FPE_ZERO use zero as the replacement value Set the flush_zero bit in the Control Status register. This causes a flush to zero without invoking the trap handler. Works only for underflow traps on the R4000 and later processors. Works like FPE_ZERO for the R3000. FPE_FLUSH_ZERO use the appropriately-typed minimum value as the replacement. (i.e., the smallest number which is representable in that format _w_i_t_h_o_u_t denormalizing) FPE_MIN use the appropriately-typed maximum value as the replacement FPE_MAX use the appropriately-typed value for infinity as the replacement FPE_INF use the appropriately-typed value for not-a-number as the replacement. (A _q_u_i_e_t not-a- number is used.) FPE_NAN use IEEE standard results as the return result for FFFFPPPPEEEE____UUUUNNNNDDDDEEEERRRRFFFFLLLL, FFFFPPPPEEEE____OOOOVVVVEEEERRRRFFFFLLLL, FFFFPPPPEEEE____DDDDIIIIVVVVZZZZEEEERRRROOOO, and FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD exceptions. FPE_APPROPRIATE invoke the routine _u_s_e_r__r_o_u_t_i_n_e (see note) to set the value of the operation. If this is the code used for FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD exceptions, all such exceptions will defer to _u_s_e_r__r_o_u_t_i_n_e to set their value. In this case, _i_n_v_a_l_i_d_o_p__r_e_s_u_l_t_s_ and _i_n_v_a_l_i_d_o_p__o_p_e_r_a_n_d_s_ will be ignored. FPE_USER_DETERMINED use the negative of the argument as the replacement operand. This code is valid only for the cases _SQRT_NEG_X and _RSQRT_NEG_X (see FPE_NEG PPPPaaaaggggeeee 11112222 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) below). The default values used as the results of floating-point exceptions are: _________________________________________________________ values for _f_s_i_g_f_p_e()._r_e_p_l_s element # mnemonic exception condition default value _________________________________________________________ 0 (none) (ignored) 1 FPE_UNDERFL underflow FPE_APPROPRIATE 2 FPE_OVERFL overflow FPE_APPROPRIATE 3 FPE_DIVZERO divide-by-zero FPE_APPROPRIATE 4 FPE_INVALID invalid operand 0 (use tables) _________________________________________________________ |||||||||| ||||||||| ||||||||| |||||||||| The default values for FPE_OVERFL, FPE_DIVZERO, and FPE_INVALID exceptions will produce the same results as if the instruction were re- issued with the original operand(s) and floating-point traps disabled. For FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD exceptions, the correct action may be either to set the result and skip the instruction, or to replace an operand and retry the instruction. There are four cases in which the result is set. The integer array constituting the named common _i_n_v_a_l_i_d_o_p__r_e_s_u_l_t_s is consulted for replacement codes for these cases: _________________________________________________________________________ array in common block _i_n_v_a_l_i_d_o_p__r_e_s_u_l_t_s element # mnemonic exception condition default value _________________________________________________________________________ 0 (none) (ignored) 1 FPE_MAGNITUDE_INF_SUBTRACTION oo - oo FPE_NAN 2 FPE_ZERO_TIMES_INF 0 * oo FPE_NAN 3 FPE_ZERO_DIV_ZERO 0/0 FPE_NAN 4 FPE_INF_DIV_INF oo / oo FPE_NAN _________________________________________________________________________ |||||||||| ||||||||| ||||||||| |||||||||| There are ten cases in which an offending operand is replaced. An array named _i_n_v_a_l_i_d_o_p__o_p_e_r_a_n_d_s_ is consulted for user-initialized codes for these cases. Cases 8 through 11 are valid only for the mips3 and later architectures. Array _i_n_v_a_l_i_d_o_p__o_p_e_r_a_n_d_s_ has only 8 entries (0-7) for the earlier processors. Each element governs the following cases: PPPPaaaaggggeeee 11113333 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) __________________________________________________________________________ array _i_n_v_a_l_i_d_o_p__o_p_e_r_a_n_d_s_ element # mnemonic exception condition default value __________________________________________________________________________ 0 (none) (ignored) 1 FPE_SQRT_NEG_X sqrt(-x) reissue 2 (unused) (ignored) with original conversion to integer caused target to overflow 3 FPE_CVTW_OVERFL operands and 4 FPE _CVTW_NAN conversion of NaN to int floating point 5 FPE_CVTW_INF conversion of oo to int traps disabled 6 FPE_UNORDERED_CMP comparison to NaN operand was Signaling Nan 7 FPE_SNAN_OP conversion to long long caused target to overflow 8 FPE_CVTL_OVERFL 9 FPE_CVTL_NAN conversion of NaN to long long 10 FPE_CVTL_INF conversion of oo to long long 11 FPE_RSQRT_NEG_X reciprocal sqrt(-x) __________________________________________________________________________ ||||||||||||||||||| |||||||||||||||||| |||||||||||||||||| ||||||||||||||||||| NNNNOOOOTTTTEEEE UUUUsssseeee ooooffff _u_s_e_r__r_o_u_t_i_n_e ttttoooo sssseeeetttt vvvvaaaalllluuuueeeessss If the integer code defining the replacement value for a particular exception condition is _USER_DETERMINED, the user-supplied routine _u_s_e_r__r_o_u_t_i_n_e is called: ccccaaaallllllll uuuusssseeeerrrr____rrrroooouuuuttttiiiinnnneeee((((eeeexxxxcccceeeeppppttttiiiioooonnnn____ppppaaaarrrraaaammmmeeeetttteeeerrrrssss,,,, vvvvaaaalllluuuueeee)))) _v_a_l_u_e is an array of two _i_n_t * _4s into which _u_s_e_r__r_o_u_t_i_n_e should store the replacement value. If an operand is being replaced, _v_a_l_u_e has a copy of the current operand. _e_x_c_e_p_t_i_o_n__p_a_r_a_m_e_t_e_r_s is an array of five _i_n_t * _4s which describe the exception condition: PPPPaaaaggggeeee 11114444 FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) FFFFSSSSIIIIGGGGFFFFPPPPEEEE((((3333FFFF)))) ____________________________________________________________________ array _e_x_c_e_p_t_i_o_n__p_a_r_a_m_e_t_e_r_s element # mnemonic description ____________________________________________________________________ 0 FPE_EXCEPTION_TYPE the exception type (FPE_DIVZERO, etc). value = FPE_SET_RESULT if result is being set. value = FPE_REPL_OPERAND if an operand is being replaced. This element is meaningful only if the exception type is FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD. 1 FPE_INVALID_ACTION This element is meaningful only if the exception type is FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD. It is the index corresponding to the particular conditions giving rise to the exception. In conjunction with element 1, this value uniquely determines the exception condition. (e.g., if FPE_INVALID_ACTION is FPE_SET_RESULT and FPE_INVALID_TYPE is 2, the FFFFPPPPEEEE____IIIINNNNVVVVAAAALLLLIIIIDDDD exception is due to FPE_ZERO_TIMES_INF.) 2 FPE_INVALID_TYPE the type of the replacement value - either FPE_SINGLE, FPE_DOUBLE, FPE_WORD, or FPE_LONGWORD. 3 FPE_VALUE_TYPE the suggested sign _u_s_e_r__r_o_u_t_i_n_e should use for the replacement value - either FPE_POSITIVE or FPE_NEGATIVE. 4 FPE_VALUE_SIGN ____________________________________________________________________ |||||||||||||||||||||||||||| ||||||||||||||||||||||||||| |||||||||||||||||||||||||||| NNNNOOOOTTTTEEEESSSS FFFFOOOORRRR RRRR8888000000000000 Due to the nature of parallel operations on the R8000 processor, it is not possible to determine the true value of the program counter when a floating point exception occurs. Therefore, on that processor, libfpe.so will not update either operands or results when floating point exceptions occur. Another anomaly on this processor is that counts of floating point exceptions for a particular program may vary from run to run. When the R8000 processor executes in precise exception mode, libfpe behaves as it does on other processors, i.e. operands and results can be updated when floating point exceptions occur. See fpmode(1). NNNNOOOOTTTTEEEESSSS Use of the 6.2 beta version of libfpe requires a 6.2 beta operating system (or later version). SSSSEEEEEEEE AAAALLLLSSSSOOOO signal(3c), sigfpe(3c), fpc(3c), get_fpc_csr(3c), set_fp_csr(3c) PPPPaaaaggggeeee 11115555